package com.iwjw.ibatis.util;

import com.iwjw.ibatis.annotations.OptimisticKey;
import com.iwjw.ibatis.annotations.PrimaryKey;
import com.iwjw.ibatis.entity.ColumnInfo;
import com.iwjw.ibatis.entity.TableInfo;
import com.iwjw.ibatis.exception.IWMybatisException;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.TypeHandler;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * @author weiwei.huang
 * @Time 2016/10/19
 */
public class TableInfoUtil {

    /**
     * 对象解析表对应信息
     *
     * @param clazz
     * @return
     */
    public static TableInfo init(Class<?> clazz) throws IWMybatisException {
        String tableName = clazz.getName();
        String resultMap = "";
        TableInfo tableInfo = new TableInfo();
        Annotation annotation = clazz.getAnnotation(com.iwjw.ibatis.annotations.Table.class);
        if (annotation != null) {
            com.iwjw.ibatis.annotations.Table table = (com.iwjw.ibatis.annotations.Table) annotation;
            if (!StringUtils.isEmpty(table.name())) {
                tableName = table.name();
            }
            if (!StringUtils.isEmpty(table.resultMap())) {
                resultMap = table.resultMap();
            }
        }
        Field[] fields = clazz.getDeclaredFields();
        List<ColumnInfo> columnInfoList = new ArrayList();
        for (Field field : fields) {
            ColumnInfo columnInfo = buildColumn(field);
            if (columnInfo == null) {
                continue;
            }
            columnInfoList.add(columnInfo);
            if (field.getAnnotation(PrimaryKey.class) != null) {
                //已经有主键，又解析出主键，异常报错
                if (tableInfo.getPrimary() != null) {
                    throw new IWMybatisException();
                }
                PrimaryKey primaryKeyAnnotation = field.getAnnotation(PrimaryKey.class);
                Boolean isAuto = primaryKeyAnnotation.isAuto();
                tableInfo.setIsAuto(isAuto);
                tableInfo.setPrimary(columnInfo);
            }

            if (field.getAnnotation(OptimisticKey.class) != null) {
                //已经有主键，又解析出主键，异常报错
                if (tableInfo.getOptimistic() != null) {
                    throw new IWMybatisException();
                }
                tableInfo.setOptimistic(columnInfo);
            }
        }
        tableInfo.setColumnInfoList(columnInfoList);
        tableInfo.setName(tableName);
        tableInfo.setResultMap(resultMap);
        tableInfo.setModelName(clazz.getSimpleName());
        return tableInfo;
    }


    private static ColumnInfo buildColumn(Field field) {
        //如果是静态变量直接过滤掉
        if (Modifier.isStatic(field.getModifiers())) {
            return null;
        }
        Annotation annotation = field.getAnnotation(com.iwjw.ibatis.annotations.Column.class);
        ColumnInfo columnInfo = new ColumnInfo();
        columnInfo.setName(field.getName());
        columnInfo.setProperty(field.getName());
        if (annotation == null) {
            return columnInfo;
        }
        com.iwjw.ibatis.annotations.Column columnAnnotation = (com.iwjw.ibatis.annotations.Column) annotation;
        if (!columnAnnotation.exist()) {
            return null;
        }
        if (!StringUtils.isEmpty(columnAnnotation.name())) {
            columnInfo.setName(columnAnnotation.name());
        }
        if (columnAnnotation.javaType() != null) {
            columnInfo.setJavaType(field.getType());
        }
        if (columnAnnotation.typeHandler() != null && !columnAnnotation.typeHandler().equals(TypeHandler.class)) {
            columnInfo.setTypeHandler(columnAnnotation.typeHandler());
        }
        if (!StringUtils.isEmpty(columnAnnotation.jdbcType())) {
            columnInfo.setJdbcType(columnAnnotation.jdbcType());
        }
        return columnInfo;
    }
}
